/*CRM Helper*/
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
// Namespace container for functions in this library..
//var this.serverUrl() = getServerUrl();
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc";
var OrganizationUrl = "/XRMServices/2011/Organization.svc/web";
var Execute = "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute";
SDK.CrmData = {
    serverUrl: function () {///<summary>
        /// Private function used to establish the path to the SOAP endpoint based on context
        /// provided by the Xrm.Page object or the context object returned by the GlobalContext object.
        ///</summary>
        var url = this._Context().getServerUrl();
        if (url.match(/\/$/)) {
            url = url.substring(0, url.length - 1);
        }
        var locationhref = location.href;
        if (locationhref.indexOf(url) == -1) {
            var serverIndex = url.lastIndexOf("/");

            var serverUrl = url.substring(0, serverIndex);
            url = url.replace(serverUrl, locationhref.substring(0, locationhref.indexOf(url.substring(serverIndex))));
        }
        return url;
    },
    _Context: function () {
        var errorMessage = "Context is not available.";
        if (typeof GetGlobalContext != "undefined")
        { return GetGlobalContext(); }
        else {
            if (typeof Xrm != "undefined") {
                return Xrm.Page.context;
            }
            else
            { return new Error(errorMessage); }
        }
    },
    CreateRecord: function (entityObject, odataSetName) {
        if (!entityObject) {
            alert("entityObject is required.");
            return;
        }
        if (!odataSetName) {
            alert("odataSetName is required.");
            return;
        }

        //var jsonEntity = parent.window.JSON.stringify(entityObject);
		var jsonEntity = JSON.stringify(entityObject);
        var createAccountReq = new XMLHttpRequest();
        createAccountReq.open("POST", this.serverUrl() + ODATA_ENDPOINT + "/" + odataSetName, false);
        createAccountReq.setRequestHeader("Accept", "application/json");
        createAccountReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        createAccountReq.send(jsonEntity);		
        if (createAccountReq.readyState == 4 /* complete */) {			
            if (createAccountReq.status == 201) {
                //return parent.window.JSON.parse(createAccountReq.responseText).d;
				return JSON.parse(createAccountReq.responseText).d;
                //return true;
            }
            else {
                //Failure
                this.errorHandler(createAccountReq);
                return null;
                //showMessage("createAccountReqCallBack function failure END");
            }
        }
    },
	RetrieveRecordsByUrl:function(odataUri)
	{
	  var retrieveReq = new XMLHttpRequest();
        retrieveReq.open("GET", odataUri, false);
        retrieveReq.setRequestHeader("Accept", "application/json");
        retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        retrieveReq.send();
        if (retrieveReq.status == 200) {
            var data = parent.window.JSON.parse(retrieveReq.responseText);
            // if (data && data.d && data.d.__next==null) {
            // return data.d.results;
            // }
            // else
            if (data && data.d) {
                return data.d;
            }
            else {
                return data;
            }

            }
        else {
            //Failure
            this.errorHandler(retrieveReq);
        }
	},
    RetrieveRecord: function (id, odataSetName, filter) {

        //id is required
        if (!id) {
            alert("record id is required.");
            return;
        }
        //odataSetName is required, i.e. "AccountSet"
        if (!odataSetName) {
            alert("odataSetName is required.");
            return;
        }
        var odataUri = ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')";
        if (filter) {
            odataUri += filter;
        }
        //var reqParam = "(guid'" + id + "')";
        var retrieveReq = new XMLHttpRequest();
        retrieveReq.open("GET", this.serverUrl() + odataUri, false);
        retrieveReq.setRequestHeader("Accept", "application/json");
        retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        retrieveReq.send();
        if (retrieveReq.status == 200) {
			//alert(retrieveReq.responseText);
            var newAccount = JSON.parse(retrieveReq.responseText).d;
			
        }
        else {
            //Failure
			this.errorHandler(retrieveReq);
        }
        return newAccount;
    },
    RetrieveAll: function (odataSetName, filter, records, next) {
		
        if (!next) {
            next = 0;
            var res = this.RetrieveMultiple(odataSetName, filter);			
            if (res != null) {					
                if (res.__next == null)	
					{	
						return res.results;
					}
                else {	
                    next++;
                    return this.RetrieveAll(odataSetName, res.__next.substring(res.__next.indexOf("?")), records, true);
                }
            }
        }
        else {
            var res = this.RetrieveMultiple(odataSetName, filter);
            if (res != null) {
		
                records = records.concat(res.results)
                if (res.__next == null)
                    return records;

                else {
                    next++;
                    return this.RetrieveAll(odataSetName, res.__next.substring(res.__next.indexOf("?")), records, true);
                }

            }
            //   return records;
        }
        // return records;
    },
    RetrieveMultiple: function (odataSetName, filter) {
	    
        //odataSetName is required, i.e. "AccountSet"
        if (!odataSetName) {
            alert("odataSetName is required.");
            return;
        }

        //Build the URI
        var odataUri = this.serverUrl() + ODATA_ENDPOINT + "/" + odataSetName;

        //If a filter is supplied, append it to the OData URI
        if (filter) {
            odataUri += filter;
        }
        var retrieveReq = new XMLHttpRequest();
        retrieveReq.open("GET", odataUri, false);
        retrieveReq.setRequestHeader("Accept", "application/json");
        retrieveReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        retrieveReq.send();
		
        if (retrieveReq.status == 200) {			
			//alert(retrieveReq.responseText);
            var data = JSON.parse(retrieveReq.responseText).d;    
			return data;
            //if (data && data.d) {
			//    return data.d;
            //}
            //else {
		//		return data;
          //  }

            //Success
            // var newAccount = parent.window.JSON.parse(retrieveReq.responseText).d;
        }
        else {
            //Failure
            this.errorHandler(retrieveReq);
        }
        //return newAccount;

    },


    UpdateRecord: function (id, entityObject, odataSetName, successCallback) {
        var updateAccountReq = new XMLHttpRequest();
        //id is required
        if (!id) {
            alert("record id is required.");
            return;
        }
        //odataSetName is required, i.e. "AccountSet"
        if (!odataSetName) {
            alert("odataSetName is required.");
            return;
        }

        //Parse the entity object into parent.window.JSON
        var jsonEntity = parent.window.JSON.stringify(entityObject);
        updateAccountReq.open("POST", this.serverUrl() + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')", false);
        updateAccountReq.setRequestHeader("Accept", "application/json");
        updateAccountReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        updateAccountReq.setRequestHeader("X-HTTP-Method", "MERGE");
        updateAccountReq.send(jsonEntity);
        if (updateAccountReq.readyState == 4 /* complete */) {
            //There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
            if (updateAccountReq.status == 204 || updateAccountReq.status == 1223) {
                //Success
                return true;
            }
            else {
                //Failure
                this.errorHandler(updateAccountReq);
                return false;
            }
        }
    },


    DeleteRecord: function (id, odataSetName) {

        //id is required
        if (!id) {
            alert("record id is required.");
            return;
        }
        //odataSetName is required, i.e. "AccountSet"
        if (!odataSetName) {
            alert("odataSetName is required.");
            return;
        }

        var deleteAccountReq = new XMLHttpRequest();
        deleteAccountReq.open("POST", this.serverUrl() + ODATA_ENDPOINT + "/" + odataSetName + "(guid'" + id + "')", false);
        deleteAccountReq.setRequestHeader("Accept", "application/json");
        deleteAccountReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        deleteAccountReq.setRequestHeader("X-HTTP-Method", "DELETE");
        deleteAccountReq.send();
        if (deleteAccountReq.readyState == 4 /* complete */) {
            //There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
            if (deleteAccountReq.status == 204 || deleteAccountReq.status == 1223) {
                //Success
                return true;
            }
            else {
                //Failure
                this.errorHandler(deleteAccountReq);
               // showMessage("deleteAccountReqCallBack function failure END");
            }
        }
    },

    errorHandler: function (xmlHttpRequest, textStatus, errorThrow) {
        var error = parent.window.JSON.parse(xmlHttpRequest.responseText);
        if (error != null && error.error.message != null) {
            var errorMesage = error.error.message.value;
            if (errorMesage.toLowerCase().indexOf("privilege") > 0) {
                alert("You do not have the permissons.");
            }
            else {
                alert(errorMesage);
            }
        }
        else {
            alert("Error : " + xmlHttpRequest.statusText);
        }
    },
    __namespace: true
    // </snippetJQueryRESTDataOperations.Functions>
},
SDK.SOAP = {
_Context: function () {
        var errorMessage = "Context is not available.";
        if (typeof GetGlobalContext != "undefined")
        { return GetGlobalContext(); }
        else {
            if (typeof Xrm != "undefined") {
                return Xrm.Page.context;
            }
            else
            { return new Error(errorMessage); }
        }
    },
    _ServerUrl: function () {///<summary>
        /// Private function used to establish the path to the SOAP endpoint based on context
        /// provided by the Xrm.Page object or the context object returned by the GlobalContext object.
        ///</summary>
        var url = this._Context().getServerUrl();
        var url = this._Context().getServerUrl();
        if (url.match(/\/$/)) {
            url = url.substring(0, url.length - 1);
        }
        var locationhref = location.href;
        if (locationhref.indexOf(url) == -1) {
            var serverIndex = url.lastIndexOf("/");

            var serverUrl = url.substring(0, serverIndex);
            url = url.replace(serverUrl, locationhref.substring(0, locationhref.indexOf(url.substring(serverIndex))));
        }
        return url;
        // return ServerUrl + "/XRMServices/2011/Organization.svc/web";
    },
    _getSOAPWrapper: function (request) {
        var SOAP = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>";
        SOAP += request;
        SOAP += "</soapenv:Body></soapenv:Envelope>";
        return SOAP;
    },
    _ExecuteRequest: function (request) {
       // request = this._getSOAPWrapper(request);
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl()+OrganizationUrl, false);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction",  "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
        //req.onreadystatechange = function () { ExecuteResponse(req, succcessCallBack, errorCallBack) };
        req.send(request);
        var resultXml = req.responseXML;
        var errorCount = resultXml.selectNodes("//error").length;
        if (errorCount != 0) {
            var msg = resultXml.selectSingleNode("//description").nodeTypedValue;

            if (typeof (suppressError) == "undefined" || suppressError == null) {
                alert("The following error was encountered: " + msg);
            }

            return null;
        } else {
            return resultXml;
        }
    },
    _getConditionExpression: function (Attributes, Operators, Values) {
        var ConditionExpression = "<d4p1:ConditionExpression>";
        for (i = 0; i < Attributes.length; i++) {
            ConditionExpression += '<d4p1:AttributeName>' + Attributes[0] + '</d4p1:AttributeName>';
            ConditionExpression += '<d4p1:Operator>' + Operators[i] + '</d4p1:Operator>'
            ConditionExpression += '<d4p1:Values xmlns:d11p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">';
            for (j = 0; j < Values[0].length; j++) {
                ConditionExpression += '<d11p1:anyType xmlns:d12p1="http://www.w3.org/2001/XMLSchema" i:type="d12p1:string">' + Values[0][j] + '</d11p1:anyType>';
            }
        }
        ConditionExpression += '</d4p1:ConditionExpression>';
    },
    RetrieveBusinessCalendersRequest: function () {
        var req = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services"><request xmlns:d4p1="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">';
        req += '<d4p1:Parameters xmlns:d5p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic">';
        req += '<d4p1:KeyValuePairOfstringanyType>';
        req += '<d5p1:key>Query</d5p1:key>';
        req += '<d5p1:value i:type="d4p1:QueryExpression">';
        req += '<d4p1:ColumnSet>';
        req += '<d4p1:AllColumns>true</d4p1:AllColumns>';
        req += '<d4p1:Columns xmlns:d9p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />';
        req += '</d4p1:ColumnSet>';
        req += '<d4p1:Criteria>';
        req += '<d4p1:Conditions>';
        req += '<d4p1:ConditionExpression>';
        req += '<d4p1:AttributeName>name</d4p1:AttributeName>';
        req += '<d4p1:Operator>Equal</d4p1:Operator>';
        req += '<d4p1:Values xmlns:d11p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">';
        req += '<d11p1:anyType xmlns:d12p1="http://www.w3.org/2001/XMLSchema" i:type="d12p1:string">Business Closure Calendar</d11p1:anyType>';
        req += '</d4p1:Values>';
        req += '</d4p1:ConditionExpression>';
        req += '</d4p1:Conditions>';
        req += '<d4p1:FilterOperator>And</d4p1:FilterOperator>';
        req += '<d4p1:Filters />';
        req += '</d4p1:Criteria>';
        req += '<d4p1:Distinct>false</d4p1:Distinct>';
        req += '<d4p1:EntityName>calendar</d4p1:EntityName>';
        req += '<d4p1:LinkEntities />';
        req += '<d4p1:Orders />';
        req += '<d4p1:PageInfo i:nil="true" />';
        req += '<d4p1:NoLock>false</d4p1:NoLock>';
        req += ' </d5p1:value>';
        req += '</d4p1:KeyValuePairOfstringanyType>';
        req += '</d4p1:Parameters>';
        req += '<d4p1:RequestId i:nil="true" />';
        req += '<d4p1:RequestName>RetrieveMultiple</d4p1:RequestName>';
        req += '</request></Execute></s:Body></s:Envelope>';
        return this._ExecuteRequest(req);
    },
    __namespace: true
},
SDK.MetaData = {
    _Context: function () {
        var errorMessage = "Context is not available.";
        if (typeof GetGlobalContext != "undefined")
        { return GetGlobalContext(); }
        else {
            if (typeof Xrm != "undefined") {
                return Xrm.Page.context;
            }
            else
            { return new Error(errorMessage); }
        }
    },
    _ServerUrl: function () {///<summary>
        /// Private function used to establish the path to the SOAP endpoint based on context
        /// provided by the Xrm.Page object or the context object returned by the GlobalContext object.
        ///</summary>
        var url = this._Context().getServerUrl();
        var url = this._Context().getServerUrl();
        if (url.match(/\/$/)) {
            url = url.substring(0, url.length - 1);
        }
        var locationhref = location.href;
        if (locationhref.indexOf(url) == -1) {
            var serverIndex = url.lastIndexOf("/");

            var serverUrl = url.substring(0, serverIndex);
            url = url.replace(serverUrl, locationhref.substring(0, locationhref.indexOf(url.substring(serverIndex))));
        }
        return url;
        // return ServerUrl + "/XRMServices/2011/Organization.svc/web";
    },
    SetStateRequest: function (eNmae, eId, state, status) {
        var requestMain = ""
        requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        requestMain += "  <s:Body>";
        requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        requestMain += "      <request i:type=\"b:SetStateRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\" xmlns:b=\"http://schemas.microsoft.com/crm/2011/Contracts\">";
        requestMain += "        <a:Parameters xmlns:c=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        requestMain += "          <a:KeyValuePairOfstringanyType>";
        requestMain += "            <c:key>EntityMoniker</c:key>";
        requestMain += "            <c:value i:type=\"a:EntityReference\">";
        requestMain += "              <a:Id>" + eId + "</a:Id>";
        requestMain += "              <a:LogicalName>" + eNmae + "</a:LogicalName>";
        requestMain += "              <a:Name i:nil=\"true\" />";
        requestMain += "            </c:value>";
        requestMain += "          </a:KeyValuePairOfstringanyType>";
        requestMain += "          <a:KeyValuePairOfstringanyType>";
        requestMain += "            <c:key>State</c:key>";
        requestMain += "            <c:value i:type=\"a:OptionSetValue\">";
        requestMain += "              <a:Value>" + state + "</a:Value>";
        requestMain += "            </c:value>";
        requestMain += "          </a:KeyValuePairOfstringanyType>";
        requestMain += "          <a:KeyValuePairOfstringanyType>";
        requestMain += "            <c:key>Status</c:key>";
        requestMain += "            <c:value i:type=\"a:OptionSetValue\">";
        requestMain += "              <a:Value>" + status + "</a:Value>";
        requestMain += "            </c:value>";
        requestMain += "          </a:KeyValuePairOfstringanyType>";
        requestMain += "        </a:Parameters>";
        requestMain += "        <a:RequestId i:nil=\"true\" />";
        requestMain += "        <a:RequestName>SetState</a:RequestName>";
        requestMain += "      </request>";
        requestMain += "    </Execute>";
        requestMain += "  </s:Body>";
        requestMain += "</s:Envelope>";
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl() + OrganizationUrl, false)
        // Responses will return XML. It isn't possible to return JSON.
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");
        //var successCallback = null;
        //var errorCallback = null;
        //req.onreadystatechange = function () { SDK.SAMPLES.SetStateResponse(req, successCallback, errorCallback); };
        req.send(requestMain);
        var resultXml = req.responseXML;
        if (req.readyState == 4) {
            if (req.status == 200) {
                return true;
            }
            else {
                var error = SDK.MetaData._getError(req);
                if (error.message.indexOf("CheckPrivilege failed") > -1) {
                    error.message = "You do not have the permissons.";
                }
                //error.message.substring(error.message.indexOf("prv"),105)
                alert(error.message);
                return;
            }
        }

    },
    RetrieveAllEntitiesAsync: function (EntityFilters, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        ///<summary>
        /// Sends an asynchronous RetrieveAllEntities Request to retrieve all entities in the system
        ///</summary>
        ///<returns>entityMetadataCollection</returns>
        ///<param name="EntityFilters" type="String">
        /// SDK.MetaData.EntityFilters provides dictionary for the filters available to filter which data is retrieved.
        /// Alternatively a string consisting of the values 'Entity Attributes Relationships Privileges' can be used directly.
        /// Include only those elements of the entity you want to retrieve. Retrieving all parts of all entitities may take significant time.
        ///</param>
        ///<param name="RetrieveAsIfPublished" type="Boolean">
        /// Sets whether to retrieve the metadata that has not been published.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function that will be passed through and be called by a successful response.
        /// This function must accept the entityMetadataCollection as a parameter.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>

        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveAllEntitiesRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityFilters</b:key>";
        request += "<b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">" + EntityFilters + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAllEntities</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl() + OrganizationUrl, true);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);
    },
    RetrieveAllEntitiesAsync: function (EntityFilters, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        ///<summary>
        /// Sends an asynchronous RetrieveAllEntities Request to retrieve all entities in the system
        ///</summary>
        ///<returns>entityMetadataCollection</returns>
        ///<param name="EntityFilters" type="String">
        /// SDK.MetaData.EntityFilters provides dictionary for the filters available to filter which data is retrieved.
        /// Alternatively a string consisting of the values 'Entity Attributes Relationships Privileges' can be used directly.
        /// Include only those elements of the entity you want to retrieve. Retrieving all parts of all entitities may take significant time.
        ///</param>
        ///<param name="RetrieveAsIfPublished" type="Boolean">
        /// Sets whether to retrieve the metadata that has not been published.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function that will be passed through and be called by a successful response.
        /// This function must accept the entityMetadataCollection as a parameter.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>

        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveAllEntitiesRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityFilters</b:key>";
        request += "<b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">" + EntityFilters + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAllEntities</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl() + OrganizationUrl, true);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        req.onreadystatechange = function () { SDK.MetaData._returnAllEntities(req, successCallBack, errorCallBack) };
        req.send(request);
    },
    _returnAllEntities: function (resp, successCallBack, errorCallBack) {
        ///<summary>
        /// Private function that processes the response from SDK.MetaData.RetrieveAllEntitiesAsync
        ///</summary>
        ///<param name="resp" type="XMLHttpRequest">
        /// The XMLHttpRequest representing the response.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function passed through to be executed when a successful retrieval is complete.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>
        if (resp.readyState == 4 /* complete */) {
            if (resp.status == 200) {
                //Success				
                var entityMetadataNodes = resp.responseXML.selectNodes("//c:EntityMetadata");
                var entityMetadataCollection = [];
                for (var i = 0; i < entityMetadataNodes.length; i++) {
                    var entityMetadata = new SDK.MetaData._entityMetaData(entityMetadataNodes[i])
                    entityMetadataCollection.push(entityMetadata);
                }
                entityMetadataCollection.sort();
                successCallBack(entityMetadataCollection);

            }
            else {

                errorCallBack(SDK.MetaData._getError(resp));

            }

        }
    },
    RetrieveEntity: function (EntityFilters, LogicalName, MetadataId, RetrieveAsIfPublished) {
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveEntityRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityFilters</b:key>";
        request += "<b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">" + EntityFilters + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        if (MetadataId == null)
        { MetadataId = "00000000-0000-0000-0000-000000000000"; }
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>MetadataId</b:key>";
        request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>LogicalName</b:key>";
        request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + LogicalName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveEntity</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl() + OrganizationUrl, false);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        //req.onreadystatechange = function () { SDK.MetaData._returnEntity(req, successCallBack, errorCallBack) };
        req.send(request);

        var resultXml = req.responseXML;
        if (req.readyState == 4 /* complete */) {
            if (req.status == 200) {
                return new SDK.MetaData._entityMetaData(resultXml.selectSingleNode("//b:value"), LogicalName);
            }
            else {
                var error = SDK.MetaData._getError(req);
                if (error.message.indexOf("CheckPrivilege failed") > -1) {
                    error.message = "You do not have the permissons.";
                }
                //error.message.substring(error.message.indexOf("prv"),105)
                alert(error.message);
                return;
            }
        }

    },
    RetrieveEntityAsync: function (EntityFilters, LogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        ///<summary>
        /// Sends an asynchronous RetrieveEntity Request to retrieve a specific entity
        ///</summary>
        ///<returns>entityMetadata</returns>
        ///<param name="EntityFilters" type="String">
        /// SDK.MetaData.EntityFilters provides dictionary for the filters available to filter which data is retrieved.
        /// Alternatively a string consisting of the values 'Entity Attributes Relationships Privileges' can be used directly.
        /// Include only those elements of the entity you want to retrieve.
        ///</param>
        ///<param name="LogicalName" optional="true" type="String">
        /// The logical name of the entity requested. A null value may be used if a MetadataId is provided.
        ///</param>
        ///<param name="MetadataId" optional="true" type="String">
        /// A null value or an empty guid may be passed if a LogicalName is provided.
        ///</param>
        ///<param name="RetrieveAsIfPublished" type="Boolean">
        /// Sets whether to retrieve the metadata that has not been published.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function that will be passed through and be called by a successful response.
        /// This function must accept the entityMetadata as a parameter.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveEntityRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityFilters</b:key>";
        request += "<b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">" + EntityFilters + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        if (MetadataId == null)
        { MetadataId = "00000000-0000-0000-0000-000000000000"; }
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>MetadataId</b:key>";
        request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>LogicalName</b:key>";
        request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + LogicalName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveEntity</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);
        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl() + OrganizationUrl, true);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        req.onreadystatechange = function () { SDK.MetaData._returnEntity(req, successCallBack, errorCallBack) };
        req.send(request);

    },
    _returnEntity: function (resp, successCallBack, errorCallBack) {
        ///<summary>
        /// Private function that processes the response from SDK.MetaData.RetrieveEntityAsync
        ///</summary>
        ///<param name="resp" type="XMLHttpRequest">
        /// The XMLHttpRequest representing the response.
        ///</param>
        ///<param name="successCallBack" type="Function">
        /// The function passed through to be executed when a successful retrieval is complete.
        ///</param>
        ///<param name="errorCallBack" type="Function">
        /// The function that will be passed through and be called by a failed response.
        /// This function must accept an Error object as a parameter.
        ///</param>
        if (resp.readyState == 4 /* complete */) {
            if (resp.status == 200) {
                //Success				
                var entityMetadata = new SDK.MetaData._entityMetaData(resp.responseXML.selectSingleNode("//b:value"));

                successCallBack(entityMetadata);

            }
            else {
                //Failure
                errorCallBack(SDK.MetaData._getError(resp));
            }
        }

    },
    RetrieveAttributeAsync: function (EntityLogicalName, LogicalName, MetadataId, RetrieveAsIfPublished, successCallBack, errorCallBack) {
        var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
        request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
        request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>EntityLogicalName</b:key>";
        request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + EntityLogicalName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        if (MetadataId == null)
        { MetadataId = "00000000-0000-0000-0000-000000000000"; }
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>MetadataId</b:key>";
        request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>RetrieveAsIfPublished</b:key>";
        request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "<a:KeyValuePairOfstringanyType>";
        request += "<b:key>LogicalName</b:key>";
        request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + LogicalName + "</b:value>";
        request += "</a:KeyValuePairOfstringanyType>";
        request += "</a:Parameters>";
        request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAttribute</a:RequestName></request>";
        request += "</Execute>";
        request = this._getSOAPWrapper(request);

        var req = new XMLHttpRequest();
        req.open("POST", this._ServerUrl() + OrganizationUrl, true);
        req.setRequestHeader("Accept", "application/xml, text/xml, */*");
        req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
        req.setRequestHeader("SOAPAction", this._Action.Execute);
        req.onreadystatechange = function () { SDK.MetaData._returnAttribute(req, successCallBack, errorCallBack) };
        req.send(request);
    },
    _returnAttribute: function (resp, successCallBack, errorCallBack) {
        if (resp.readyState == 4 /* complete */) {
            if (resp.status == 200) {
                //Success				
                //var attributeMetadata = new SDK.MetaData._attributeMetadata(resp.responseXML.selectSingleNode("//b:value"));


                var attributeData = resp.responseXML.selectSingleNode("//b:value");
                var attributeType = attributeData.selectSingleNode("c:AttributeType").text;
                var attribute = {};
                switch (attributeType) {
                    case "BigInt":
                        attribute = new SDK.MetaData._bigIntAttributeMetadata(attributeData);
                        break;
                    case "Boolean":
                        attribute = new SDK.MetaData._booleanAttributeMetadata(attributeData);
                        break;
                    case "CalendarRules":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Customer":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "DateTime":
                        attribute = new SDK.MetaData._dateTimeAttributeMetadata(attributeData);
                        break;
                    case "Decimal":
                        attribute = new SDK.MetaData._decimalAttributeMetadata(attributeData);
                        break;
                    case "Double":
                        attribute = new SDK.MetaData._doubleAttributeMetadata(attributeData);
                        break;
                    case "EntityName":
                        attribute = new SDK.MetaData._entityNameAttributeMetadata(attributeData);
                        break;
                    case "Integer":
                        attribute = new SDK.MetaData._integerAttributeMetadata(attributeData);
                        break;
                    case "Lookup":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "ManagedProperty":
                        attribute = new SDK.MetaData._managedPropertyAttributeMetadata(attributeData);
                        break;
                    case "Memo":
                        attribute = new SDK.MetaData._memoAttributeMetadata(attributeData);
                        break;
                    case "Money":
                        attribute = new SDK.MetaData._moneyAttributeMetadata(attributeData);
                        break;
                    case "Owner":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "PartyList":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Picklist":
                        attribute = new SDK.MetaData._picklistAttributeMetadata(attributeData);
                        break;
                    case "State":
                        attribute = new SDK.MetaData._stateAttributeMetadata(attributeData);
                        break;
                    case "Status":
                        attribute = new SDK.MetaData._statusAttributeMetadata(attributeData);
                        break;
                    case "String":
                        attribute = new SDK.MetaData._stringAttributeMetadata(attributeData);
                        break;
                    case "Uniqueidentifier":
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);
                        break;
                    case "Virtual": //Contains the text value of picklist fields
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);

                        break;
                }


                successCallBack(attribute);

            }
            else {
                //Failure
                errorCallBack(SDK.MetaData._getError(resp));
            }
        }
    },
    _getError: function (resp) {
        ///<summary>
        /// Private function that attempts to parse errors related to connectivity or WCF faults.
        ///</summary>
        ///<param name="resp" type="XMLHttpRequest">
        /// The XMLHttpRequest representing failed response.
        ///</param>

        //Error descriptions come from http://support.microsoft.com/kb/193625
        if (resp.status == 12029)
        { return new Error("The attempt to connect to the server failed."); }
        if (resp.status == 12007)
        { return new Error("The server name could not be resolved."); }
        var faultXml = resp.responseXML;
        var errorMessage = "Unknown (unable to parse the fault)";
        if (typeof faultXml == "object") {

            var bodyNode = faultXml.firstChild.firstChild;

            //Retrieve the fault node
            for (var i = 0; i < bodyNode.childNodes.length; i++) {
                var node = bodyNode.childNodes[i];

                //NOTE: This comparison does not handle the case where the XML namespace changes
                if ("s:Fault" == node.nodeName) {
                    for (var j = 0; j < node.childNodes.length; j++) {
                        var faultStringNode = node.childNodes[j];
                        if ("faultstring" == faultStringNode.nodeName) {
                            errorMessage = faultStringNode.text;
                            break;
                        }
                    }
                    break;
                }
            }
        }

        return new Error(errorMessage);

    },
    EntityFilters: {
        All: "Entity Attributes Relationships Privileges",
        Default: "Entity Attributes Relationships Privileges",
        Attributes: "Attributes",
        Entity: "Entity",
        Privileges: "Privileges",
        Relationships: "Relationships"
    },
    _Action: {
        Execute: "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"
    },
    _getSOAPWrapper: function (request) {
        ///<summary>
        /// Private function that wraps a soap envelope around a request.
        ///</summary>
        var SOAP = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Body>";
        SOAP += request;
        SOAP += "</soapenv:Body></soapenv:Envelope>";
        return SOAP;
    },
    _associatedMenuConfiguration: function (node) {
        ///<summary>
        /// Private function that parses xml data describing AssociatedMenuConfiguration
        ///</summary>
        var orderValue;
        if (isNaN(parseInt(node.selectSingleNode("c:Order").text, 10)))
        { orderValue = null; }
        else
        { orderValue = parseInt(node.selectSingleNode("c:Order").text, 10); }
        return {
            Behavior: node.selectSingleNode("c:Behavior").text,
            Group: node.selectSingleNode("c:Group").text,
            Label: new SDK.MetaData._label(node.selectSingleNode("c:Label")),
            Order: orderValue
        };
    },
    _oneToManyRelationshipMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing OneToManyRelationshipMetadata
        ///</summary>
        return { OneToManyRelationshipMetadata: {
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            IsCustomRelationship: (node.selectSingleNode("c:IsCustomRelationship").text == "true") ? true : false,
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsManaged: (node.selectSingleNode("c:IsManaged").text == "true") ? true : false,
            IsValidForAdvancedFind: (node.selectSingleNode("c:IsValidForAdvancedFind").text == "true") ? true : false,
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            SecurityTypes: node.selectSingleNode("c:SecurityTypes").text,
            AssociatedMenuConfiguration: new SDK.MetaData._associatedMenuConfiguration(node.selectSingleNode("c:AssociatedMenuConfiguration")),
            CascadeConfiguration: {
                Assign: node.selectSingleNode("c:CascadeConfiguration/c:Assign").text,
                Delete: node.selectSingleNode("c:CascadeConfiguration/c:Delete").text,
                Merge: node.selectSingleNode("c:CascadeConfiguration/c:Merge").text,
                Reparent: node.selectSingleNode("c:CascadeConfiguration/c:Reparent").text,
                Share: node.selectSingleNode("c:CascadeConfiguration/c:Share").text,
                Unshare: node.selectSingleNode("c:CascadeConfiguration/c:Unshare").text
            },
            ReferencedAttribute: node.selectSingleNode("c:ReferencedAttribute").text,
            ReferencedEntity: node.selectSingleNode("c:ReferencedEntity").text,
            ReferencingAttribute: node.selectSingleNode("c:ReferencingAttribute").text,
            ReferencingEntity: node.selectSingleNode("c:ReferencingEntity").text
        }
        };
    },
    _manyToManyRelationshipMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing ManyToManyRelationshipMetadata
        ///</summary>
        return { ManyToManyRelationshipMetadata: {
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            IsCustomRelationship: (node.selectSingleNode("c:IsCustomRelationship").text == "true") ? true : false,
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsManaged: (node.selectSingleNode("c:IsManaged").text == "true") ? true : false,
            IsValidForAdvancedFind: (node.selectSingleNode("c:IsValidForAdvancedFind").text == "true") ? true : false,
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            SecurityTypes: node.selectSingleNode("c:SecurityTypes").text,
            Entity1AssociatedMenuConfiguration: new SDK.MetaData._associatedMenuConfiguration(node.selectSingleNode("c:Entity1AssociatedMenuConfiguration")),
            Entity1IntersectAttribute: node.selectSingleNode("c:Entity1IntersectAttribute").text,
            Entity1LogicalName: node.selectSingleNode("c:Entity1LogicalName").text,
            Entity2AssociatedMenuConfiguration: new SDK.MetaData._associatedMenuConfiguration(node.selectSingleNode("c:Entity2AssociatedMenuConfiguration")),
            Entity2IntersectAttribute: node.selectSingleNode("c:Entity2IntersectAttribute").text,
            Entity2LogicalName: node.selectSingleNode("c:Entity2LogicalName").text,
            IntersectEntityName: node.selectSingleNode("c:IntersectEntityName").text
        }
        };
    },
    _entityMetaData: function (node, entityName) {
        ///<summary>
        /// Private function that parses xml data describing EntityMetaData
        ///</summary>
        //Check for Attributes and add them if they are included.
        var attributes = new Object();
        var attributesData = node.selectSingleNode("c:Attributes")
        if (attributesData.childNodes.length > 0) {
            //There are attributes
            for (var i = 0; i < attributesData.childNodes.length; i++) {
                var attributeData = attributesData.childNodes[i];
                var attributeType = attributeData.selectSingleNode("c:AttributeType").text;
                var attribute = new Object();
                attribute.EntityLogicalName = entityName;
                attribute.LogicalName = attributeData.selectSingleNode("c:LogicalName").text;
                switch (attributeType) {
                    case "BigInt":
                        attribute = new SDK.MetaData._bigIntAttributeMetadata(attributeData);
                        break;
                    case "Boolean":
                        attribute = new SDK.MetaData._booleanAttributeMetadata(attributeData);
                        break;
                    case "CalendarRules":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Customer":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "DateTime":
                        attribute = new SDK.MetaData._dateTimeAttributeMetadata(attributeData);
                        break;
                    case "Decimal":
                        attribute = new SDK.MetaData._decimalAttributeMetadata(attributeData);
                        break;
                    case "Double":
                        attribute = new SDK.MetaData._doubleAttributeMetadata(attributeData);
                        break;
                    case "EntityName":
                        attribute = new SDK.MetaData._entityNameAttributeMetadata(attributeData);
                        break;
                    case "Integer":
                        attribute = new SDK.MetaData._integerAttributeMetadata(attributeData);
                        break;
                    case "Lookup":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "ManagedProperty":
                        attribute = new SDK.MetaData._managedPropertyAttributeMetadata(attributeData);
                        break;
                    case "Memo":
                        attribute = new SDK.MetaData._memoAttributeMetadata(attributeData);
                        break;
                    case "Money":
                        attribute = new SDK.MetaData._moneyAttributeMetadata(attributeData);
                        break;
                    case "Owner":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "PartyList":
                        attribute = new SDK.MetaData._lookupAttributeMetadata(attributeData);
                        break;
                    case "Picklist":
                        attribute = new SDK.MetaData._picklistAttributeMetadata(attributeData);
                        break;
                    case "State":
                        attribute = new SDK.MetaData._stateAttributeMetadata(attributeData);
                        break;
                    case "Status":
                        attribute = new SDK.MetaData._statusAttributeMetadata(attributeData);
                        break;
                    case "String":
                        attribute = new SDK.MetaData._stringAttributeMetadata(attributeData);
                        break;
                    case "Uniqueidentifier":
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);
                        break;
                    case "Virtual": //Contains the text value of picklist fields
                        attribute = new SDK.MetaData._attributeMetadata(attributeData);

                        break;
                }
                attributes[attribute.LogicalName] = attribute
                //attributes.push(attribute);

            }
            //attributes.sort();
        }

        //Check for Privileges and add them if they are included.
        var privileges = [];
        var privilegesData = node.selectSingleNode("c:Privileges");
        if (privilegesData.childNodes.length > 0) {
            for (var i = 0; i < privilegesData.childNodes.length; i++) {
                var privilegeData = privilegesData.childNodes[i];
                var securityPrivilegeMetadata = {
                    SecurityPrivilegeMetadata: {
                        CanBeBasic: (privilegeData.selectSingleNode("c:CanBeBasic").text == "true") ? true : false,
                        CanBeDeep: (privilegeData.selectSingleNode("c:CanBeDeep").text == "true") ? true : false,
                        CanBeGlobal: (privilegeData.selectSingleNode("c:CanBeGlobal").text == "true") ? true : false,
                        CanBeLocal: (privilegeData.selectSingleNode("c:CanBeLocal").text == "true") ? true : false,
                        Name: privilegeData.selectSingleNode("c:Name").text,
                        PrivilegeId: privilegeData.selectSingleNode("c:PrivilegeId").text,
                        PrivilegeType: privilegeData.selectSingleNode("c:PrivilegeType").text
                    }
                };
                privileges.push(securityPrivilegeMetadata);
            }
        }

        //Check for Relationships and add them if they are included.
        var manyToManyRelationships = [];
        var manyToManyRelationshipsData = node.selectSingleNode("c:ManyToManyRelationships");
        if (manyToManyRelationshipsData.childNodes.length > 0) {
            for (var i = 0; i < manyToManyRelationshipsData.childNodes.length; i++) {
                var manyToManyRelationshipMetadataData = manyToManyRelationshipsData.childNodes[i];

                var manyToManyRelationshipMetadata = new SDK.MetaData._manyToManyRelationshipMetadata(manyToManyRelationshipMetadataData);
                manyToManyRelationships.push(manyToManyRelationshipMetadata);
            }
        }

        var manyToOneRelationships = [];
        var manyToOneRelationshipsData = node.selectSingleNode("c:ManyToOneRelationships");
        if (manyToOneRelationshipsData.childNodes.length > 0) {

            for (var i = 0; i < manyToOneRelationshipsData.childNodes.length; i++) {
                var manyToOneRelationshipMetadata = new SDK.MetaData._oneToManyRelationshipMetadata(manyToOneRelationshipsData.childNodes[i]);

                manyToOneRelationships.push(manyToOneRelationshipMetadata);

            }

        }

        var oneToManyRelationships = [];
        var oneToManyRelationshipsData = node.selectSingleNode("c:OneToManyRelationships");
        if (oneToManyRelationshipsData.childNodes.length > 0) {
            for (var i = 0; i < oneToManyRelationshipsData.childNodes.length; i++) {
                var oneToManyRelationshipMetadata = new SDK.MetaData._oneToManyRelationshipMetadata(oneToManyRelationshipsData.childNodes[i]);
                oneToManyRelationships.push(oneToManyRelationshipMetadata);
            }
        }


        return {
            ActivityTypeMask: SDK.MetaData._nullableInt(node.selectSingleNode("c:ActivityTypeMask")),
            Attributes: attributes,
            AutoRouteToOwnerQueue: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:AutoRouteToOwnerQueue")),
            CanBeInManyToMany: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanBeInManyToMany")),
            CanBePrimaryEntityInRelationship: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanBePrimaryEntityInRelationship")),
            CanBeRelatedEntityInRelationship: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanBeRelatedEntityInRelationship")),
            CanCreateAttributes: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateAttributes")),
            CanCreateCharts: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateCharts")),
            CanCreateForms: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateForms")),
            CanCreateViews: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanCreateViews")),
            CanModifyAdditionalSettings: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanModifyAdditionalSettings")),
            CanTriggerWorkflow: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanTriggerWorkflow")),
            Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
            DisplayCollectionName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayCollectionName")),
            DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
            IconLargeName: node.selectSingleNode("c:IconLargeName").text,
            IconMediumName: node.selectSingleNode("c:IconMediumName").text,
            IconSmallName: node.selectSingleNode("c:IconSmallName").text,
            IsActivity: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsActivity")),
            IsActivityParty: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsActivityParty")),
            IsAuditEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsAuditEnabled")),
            IsAvailableOffline: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsAvailableOffline")),
            IsChildEntity: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsChildEntity")),
            IsConnectionsEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsConnectionsEnabled")),
            IsCustomEntity: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomEntity")),
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsDocumentManagementEnabled: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsDocumentManagementEnabled")),
            IsDuplicateDetectionEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsDuplicateDetectionEnabled")),
            IsEnabledForCharts: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsEnabledForCharts")),
            IsImportable: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsImportable")),
            IsIntersect: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsIntersect")),
            IsMailMergeEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsMailMergeEnabled")),
            IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
            IsMappable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsMappable")),
            IsReadingPaneEnabled: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsReadingPaneEnabled")),
            IsRenameable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsRenameable")),
            IsValidForAdvancedFind: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForAdvancedFind")),
            IsValidForQueue: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsValidForQueue")),
            IsVisibleInMobile: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsVisibleInMobile")),
            LogicalName: node.selectSingleNode("c:LogicalName").text,
            ManyToManyRelationships: manyToManyRelationships,
            ManyToOneRelationships: manyToOneRelationships,
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            ObjectTypeCode: SDK.MetaData._nullableInt(node.selectSingleNode("c:ObjectTypeCode")),
            OneToManyRelationships: oneToManyRelationships,
            OwnershipType: node.selectSingleNode("c:OwnershipType").text,
            PrimaryIdAttribute: node.selectSingleNode("c:PrimaryIdAttribute").text,
            PrimaryNameAttribute: node.selectSingleNode("c:PrimaryNameAttribute").text,
            Privileges: privileges,
            RecurrenceBaseEntityLogicalName: node.selectSingleNode("c:RecurrenceBaseEntityLogicalName").text,
            ReportViewName: node.selectSingleNode("c:ReportViewName").text,
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            // So the LogicalName property will be used for an array.sort().
            toString: function () { return this.LogicalName }
        };


    },
    _nullableInt: function (node) {
        ///<summary>
        /// Private function that parses xml data describing nullable Integer values
        ///</summary>
        if (node.text == "")
        { return null; }
        else
        { return parseInt(node.text, 10); }

    },
    _nullableBoolean: function (node) {
        ///<summary>
        /// Private function that parses xml data describing nullable Boolean values
        ///</summary>
        if (node.text == "")
        { return null; }
        if (node.text == "true")
        { return true; }
        else
        { return false; }
    },
    _booleanManagedProperty: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BooleanManagedProperty 
        ///</summary>
        return {
            CanBeChanged: (node.selectSingleNode("a:CanBeChanged").text == "true") ? true : false,
            ManagedPropertyLogicalName: node.selectSingleNode("a:ManagedPropertyLogicalName").text,
            Value: (node.selectSingleNode("a:Value").text == "true") ? true : false
        };

    },
    _requiredLevelManagedProperty: function (node) {
        ///<summary>
        /// Private function that parses xml data describing AttributeRequiredLevelManagedProperty  
        ///</summary>
        if (node.selectSingleNode("a:CanBeChanged") == null) {
            return null;
        }

        return {
            CanBeChanged: (node.selectSingleNode("a:CanBeChanged").text == "true") ? true : false,
            ManagedPropertyLogicalName: node.selectSingleNode("a:ManagedPropertyLogicalName").text,
            Value: node.selectSingleNode("a:Value").text
        };

    },
    _label: function (node) {
        ///<summary>
        /// Private function that parses xml data describing Label 
        ///</summary>
        if (node.text == "") {
            return {
                LocalizedLabels: [],
                UserLocalizedLabel: null
            };
        }
        else {
            var locLabels = node.selectSingleNode("a:LocalizedLabels");
            var userLocLabel = node.selectSingleNode("a:UserLocalizedLabel");
            var arrLocLabels = [];
            for (var i = 0; i < locLabels.childNodes.length; i++) {
                var LocLabelNode = locLabels.childNodes[i];
                var locLabel = {
                    LocalizedLabel: {
                        IsManaged: (LocLabelNode.selectSingleNode("a:IsManaged").text == "true") ? true : false,
                        Label: LocLabelNode.selectSingleNode("a:Label").text,
                        LanguageCode: parseInt(LocLabelNode.selectSingleNode("a:LanguageCode").text, 10)
                    }
                };
                arrLocLabels.push(locLabel);
            }

            return {
                LocalizedLabels: arrLocLabels,
                UserLocalizedLabel: {
                    IsManaged: (userLocLabel.selectSingleNode("a:IsManaged").text == "true") ? true : false,
                    Label: userLocLabel.selectSingleNode("a:Label").text,
                    LanguageCode: parseInt(userLocLabel.selectSingleNode("a:LanguageCode").text, 10)
                }
            };

        }


    },
    _options: function (node) {
        ///<summary>
        /// Private function that parses xml data describing OptionSetMetadata Options 
        ///</summary>
        var optionMetadatas = [];
        for (var i = 0; i < node.childNodes.length; i++) {
            var optionMetadata = node.childNodes[i];
            var option;
            if (optionMetadata.attributes.getNamedItem("i:type") != null && optionMetadata.attributes.getNamedItem("i:type").value == "c:StatusOptionMetadata") {

                option = { StatusOptionMetadata:
			   { MetadataId: optionMetadata.selectSingleNode("c:MetadataId").text,
			       Description: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Description")),
			       IsManaged: SDK.MetaData._nullableBoolean(optionMetadata.selectSingleNode("c:IsManaged")),
			       Label: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Label")),
			       Value: parseInt(optionMetadata.selectSingleNode("c:Value").text, 10),
			       State: parseInt(optionMetadata.selectSingleNode("c:State").text, 10)

			   }
                };
            }
            else {
                if (optionMetadata.attributes.getNamedItem("i:type") != null && optionMetadata.attributes.getNamedItem("i:type").value == "c:StateOptionMetadata") {

                    option = { StateOptionMetadata:
			   { MetadataId: optionMetadata.selectSingleNode("c:MetadataId").text,
			       Description: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Description")),
			       IsManaged: SDK.MetaData._nullableBoolean(optionMetadata.selectSingleNode("c:IsManaged")),
			       Label: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Label")),
			       Value: parseInt(optionMetadata.selectSingleNode("c:Value").text, 10),
			       DefaultStatus: parseInt(optionMetadata.selectSingleNode("c:DefaultStatus ").text, 10),
			       InvariantName: optionMetadata.selectSingleNode("c:InvariantName").text

			   }
                    };
                }
                else {
                    option = { OptionMetadata:
			    { MetadataId: optionMetadata.selectSingleNode("c:MetadataId").text,
			        Description: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Description")),
			        IsManaged: SDK.MetaData._nullableBoolean(optionMetadata.selectSingleNode("c:IsManaged")),
			        Label: new SDK.MetaData._label(optionMetadata.selectSingleNode("c:Label")),
			        Value: parseInt(optionMetadata.selectSingleNode("c:Value").text, 10)

			    }
                    };
                }
            }


            optionMetadatas.push(option);

        }
        return optionMetadatas;
    },
    _booleanOptionSet: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BooleanOptionSetMetadata 
        ///</summary>
        if (node.childNodes.length == 0)
        { return null; }
        else {
            return {
                MetadataId: node.selectSingleNode("c:MetadataId").text,
                Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
                DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
                IsCustomOptionSet: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomOptionSet")),
                IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
                IsGlobal: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsGlobal")),
                IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
                Name: node.selectSingleNode("c:Name").text,
                OptionSetType: node.selectSingleNode("c:OptionSetType").text,
                FalseOption: {
                    MetadataId: node.selectSingleNode("c:FalseOption/c:MetadataId").text,
                    Description: new SDK.MetaData._label(node.selectSingleNode("c:FalseOption/c:Description")),
                    IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:FalseOption/c:IsManaged")),
                    Label: new SDK.MetaData._label(node.selectSingleNode("c:FalseOption/c:Label")),
                    Value: parseInt(node.selectSingleNode("c:FalseOption/c:Value").text, 10)
                },
                TrueOption: {
                    MetadataId: node.selectSingleNode("c:TrueOption/c:MetadataId").text,
                    Description: new SDK.MetaData._label(node.selectSingleNode("c:TrueOption/c:Description")),
                    IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:TrueOption/c:IsManaged")),
                    Label: new SDK.MetaData._label(node.selectSingleNode("c:TrueOption/c:Label")),
                    Value: parseInt(node.selectSingleNode("c:TrueOption/c:Value").text, 10)
                }
            };
        }


    },
    _optionSet: function (node) {
        ///<summary>
        /// Private function that parses xml data describing OptionSetMetadata 
        ///</summary>
        if (node.childNodes.length == 0)
        { return null; }
        else {
            return {
                MetadataId: node.selectSingleNode("c:MetadataId").text,
                Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
                DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
                IsCustomOptionSet: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomOptionSet")),
                IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
                IsGlobal: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsGlobal")),
                IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
                Name: node.selectSingleNode("c:Name").text,
                OptionSetType: node.selectSingleNode("c:OptionSetType").text,
                Options: new SDK.MetaData._options(node.selectSingleNode("c:Options"))
            };
        }


    },
    _attributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing AttributeMetadata 
        ///</summary>
        return {
            AttributeOf: node.selectSingleNode("c:AttributeOf").text,
            AttributeType: node.selectSingleNode("c:AttributeType").text,
            CanBeSecuredForCreate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanBeSecuredForCreate")),
            CanBeSecuredForRead: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanBeSecuredForRead")),
            CanBeSecuredForUpdate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:CanBeSecuredForUpdate")),
            CanModifyAdditionalSettings: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:CanModifyAdditionalSettings")),
            ColumnNumber: SDK.MetaData._nullableInt(node.selectSingleNode("c:ColumnNumber")),
            DeprecatedVersion: node.selectSingleNode("c:DeprecatedVersion").text,
            Description: new SDK.MetaData._label(node.selectSingleNode("c:Description")),
            DisplayName: new SDK.MetaData._label(node.selectSingleNode("c:DisplayName")),
            EntityLogicalName: node.selectSingleNode("c:EntityLogicalName").text,
            ExtensionData: null, //No node for ExtensionData
            IsAuditEnabled: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsAuditEnabled")),
            IsCustomAttribute: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsCustomAttribute")),
            IsCustomizable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsCustomizable")),
            IsManaged: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsManaged")),
            IsPrimaryId: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsPrimaryId")),
            IsPrimaryName: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsPrimaryName")),
            IsRenameable: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsRenameable")),
            IsSecured: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsSecured")),
            IsValidForAdvancedFind: new SDK.MetaData._booleanManagedProperty(node.selectSingleNode("c:IsValidForAdvancedFind")),
            IsValidForCreate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForCreate")),
            IsValidForRead: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForRead")),
            IsValidForUpdate: SDK.MetaData._nullableBoolean(node.selectSingleNode("c:IsValidForUpdate")),
            LinkedAttributeId: node.selectSingleNode("c:LinkedAttributeId").text,
            LogicalName: node.selectSingleNode("c:LogicalName").text,
            MetadataId: node.selectSingleNode("c:MetadataId").text,
            RequiredLevel: new SDK.MetaData._requiredLevelManagedProperty(node.selectSingleNode("c:RequiredLevel")),
            SchemaName: node.selectSingleNode("c:SchemaName").text,
            toString: function ()
            { return this.LogicalName; }
        };
    },
    _enumAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing EnumAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        //FIXED: DefaultFormValue was using _nullableBoolean. 
        attributeMetadata.DefaultFormValue = SDK.MetaData._nullableInt(node.selectSingleNode("c:DefaultFormValue")),
		attributeMetadata.OptionSet = new SDK.MetaData._optionSet(node.selectSingleNode("c:OptionSet"));

        return attributeMetadata;

    },
    _stateAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing StateAttributeMetadata 
        ///</summary>
        var enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return enumAttributeMetadata;
    },
    _stringAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing StringAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);

        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxLength = parseInt(node.selectSingleNode("c:MaxLength").text, 10);
        attributeMetadata.YomiOf = node.selectSingleNode("c:YomiOf").text;

        return attributeMetadata;

    },
    _managedPropertyAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing ManagedPropertyAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.ManagedPropertyLogicalName = node.selectSingleNode("c:ManagedPropertyLogicalName").text;
        attributeMetadata.ParentAttributeName = node.selectSingleNode("c:ParentAttributeName").text;
        attributeMetadata.ParentComponentType = SDK.MetaData._nullableInt(node.selectSingleNode("c:ParentComponentType"));
        attributeMetadata.ValueAttributeTypeCode = node.selectSingleNode("c:ValueAttributeTypeCode").text;

        return attributeMetadata;

    },
    _bigIntAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BigIntAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MaxValue").text;

        return attributeMetadata;

    },
    _booleanAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing BooleanAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.DefaultValue = SDK.MetaData._nullableBoolean(node.selectSingleNode("c:DefaultValue"));
        attributeMetadata.OptionSet = new SDK.MetaData._booleanOptionSet(node.selectSingleNode("c:OptionSet"));

        return attributeMetadata;
    },
    _dateTimeAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing DateTimeAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;


        return attributeMetadata;
    },
    _decimalAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing DecimalAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MinValue").text;
        attributeMetadata.Precision = parseInt(node.selectSingleNode("c:Precision").text, 10);

        return attributeMetadata;
    },
    _doubleAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing DoubleAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text,
		attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MinValue").text;
        attributeMetadata.Precision = parseInt(node.selectSingleNode("c:Precision").text, 10);

        return attributeMetadata;
    },
    _entityNameAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing EntityNameAttributeMetadata 
        ///</summary>
        var _enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return _enumAttributeMetadata;
    },
    _integerAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing IntegerAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.MaxValue = parseInt(node.selectSingleNode("c:MaxValue").text, 10);
        attributeMetadata.MinValue = parseInt(node.selectSingleNode("c:MinValue").text, 10);

        return attributeMetadata;
    },
    _picklistAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing PicklistAttributeMetadata 
        ///</summary>
        var enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);

        return enumAttributeMetadata;
    },
    _statusAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing StatusAttributeMetadata 
        ///</summary>
        var enumAttributeMetadata = new SDK.MetaData._enumAttributeMetadata(node);


        return enumAttributeMetadata;
    },
    _memoAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing MemoAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Format = node.selectSingleNode("c:Format").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxLength = parseInt(node.selectSingleNode("c:MaxLength").text, 10);

        return attributeMetadata;
    },
    _moneyAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing MoneyAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.CalculationOf = node.selectSingleNode("c:CalculationOf").text;
        attributeMetadata.ImeMode = node.selectSingleNode("c:ImeMode").text;
        attributeMetadata.MaxValue = node.selectSingleNode("c:MaxValue").text;
        attributeMetadata.MinValue = node.selectSingleNode("c:MinValue").text;
        attributeMetadata.Precision = parseInt(node.selectSingleNode("c:Precision").text, 10);
        attributeMetadata.PrecisionSource = SDK.MetaData._nullableInt(node.selectSingleNode("c:PrecisionSource"));

        return attributeMetadata;
    },
    _lookupAttributeMetadata: function (node) {
        ///<summary>
        /// Private function that parses xml data describing LookupAttributeMetadata 
        ///</summary>
        var attributeMetadata = new SDK.MetaData._attributeMetadata(node);
        attributeMetadata.Targets = null;
        var targets = targets = node.selectSingleNode("c:Targets").childNodes
        if (targets.length > 0) {
            attributeMetadata.Targets = new Array();

            for (index = 0; index < targets.length; index++) {
                var targetNode = targets.item(index);
                attributeMetadata.Targets.push(targetNode.nodeTypedValue);
            }
        }
        return attributeMetadata;
    },
    __namespace: true
};


/*CRM Helper*/